package com.dk.service.impl;

import com.dk.enums.PositionEnum;
import com.dk.mapper.PlayerDataMapper;
import com.dk.mapper.PlayerPositionMapper;
import com.dk.pojo.PlayerPosition;
import com.dk.pojo.playerData.PlayerData;
import com.dk.pojo.playerData.PlayerDataExample;
import com.dk.pojo.playerData.PlayerDataVO;
import com.dk.service.PlayerDataService;
import com.dk.util.CustomUtils;
import com.dk.util.MD5Utils;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletRequest;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Service
public class PlayerDataServiceImpl implements PlayerDataService {
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private PlayerDataMapper playerDataMapper;
    @Autowired
    private PlayerPositionMapper playerPositionMapper;

    @Override
    public Integer getInfo(PlayerData playerData, HttpServletRequest request) {
        //未注册
        PlayerData playerDataPO = playerDataMapper.seleteByAccount(playerData.getPlayerAccount());
        if (playerDataPO == null) return 1;

        String key = "Player:";
        Integer playerId = playerDataPO.getPlayerId();
        HashOperations hashOperations = redisTemplate.opsForHash();
        Boolean b = hashOperations.hasKey(key, playerId);
        if (!b){
            hashOperations.put(key,playerId,0);
        }

        // 账号已冻结
        if ((Integer)hashOperations.get(key,playerId) >= 3) return 2;

        Integer value = (Integer) hashOperations.get(key,playerId);
        try {
            //输入密码与数据库反解析密码对比
            if (!MD5Utils.validPassword(playerData.getPlayerPw(),playerDataPO.getPlayerPw())){
                hashOperations.put(key,playerId,value + 1);
                return 3;
            }
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }

        if (value > 0) hashOperations.put(key,playerId,0);

        request.getSession().setAttribute("player",playerDataPO);
        return 4;
    }

    @Override
    public Integer selectUser(PlayerData playerData) {
        PlayerData playerDataPO = playerDataMapper.seleteByAccount(playerData.getPlayerAccount());
        if (playerDataPO != null){
            return 1;
        }else {
            return 2;
        }
    }

    @Override
    public PageInfo<PlayerData> show(PlayerData playerData,Integer pageNumber, Integer pageSize) {
        PageHelper.startPage(pageNumber,pageSize);
        PlayerDataExample example = new PlayerDataExample();
        PlayerDataExample.Criteria criteria = example.createCriteria();
        if (playerData.getPlayerAccount() != null){
            criteria.andPlayerAccountEqualTo(playerData.getPlayerAccount());
        }
        List<PlayerData> list = playerDataMapper.selectByExample(example);
        //展示前端时权限中文化(暂时不能加，加了就有bug）
//        List<PlayerDataVO> playerDataVOList = list.stream().map(playerData -> {
//            PlayerDataVO playerDataVO = new PlayerDataVO();
//            BeanUtils.copyProperties(playerData,playerDataVO);
//            playerDataVO.setPositionId(PositionEnum.getExprByCode(playerData.getPositionId()));
//            return playerDataVO;
//        }).collect(Collectors.toList());
        PageInfo<PlayerData> page = new PageInfo<>(list);
        return page;
    }

    @Override
    public List<PlayerData> getInfoToo() {
        return playerDataMapper.selectByExample(null);
    }

    @Override
    @Transactional(rollbackFor = {Throwable.class})
    public boolean addInfo(PlayerData playerData) {
        //随机生成一个6位数账号
        playerData .setPlayerAccount(CustomUtils.account());
        try {
            //初始密码固定123
            playerData.setPlayerPw(MD5Utils.getEncryptedPwd("123"));
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        playerData.setCrtTime(new Date());
        playerData.setUptTime(new Date());
        //积分初始值为0
        playerData.setPlayerScore(new BigDecimal(0));
        PlayerPosition position = new PlayerPosition();
        //玩家权限表
        position.setPlayerAccount(playerData.getPlayerAccount());
        position.setPositionId(playerData.getPositionId());
        playerPositionMapper.insert(position);
        return playerDataMapper.insert(playerData) > 0;
    }

    @Override
    public PlayerData toUpdatet(Integer id) {
        return playerDataMapper.selectByPrimaryKey(id);
    }

    @Override
    @Transactional(rollbackFor = {Throwable.class})
    public boolean updateInfo(PlayerData playerData) {
        //获取玩家账号
        Integer playerAccount = playerData.getPlayerAccount();
        //如果redis中已经记录了其权限，那么修改后需要删除树状记录
        String key = "permission";
        String field = "menu:info:" + playerAccount;
        //如果存在，直接删除
        HashOperations hashJedis = redisTemplate.opsForHash();
        hashJedis.delete(key,field);
        PlayerPosition position = new PlayerPosition();
        //玩家权限表
        position.setPlayerAccount(playerAccount);
        position.setPositionId(playerData.getPositionId());
        playerPositionMapper.updateByAccout(position);
        return playerDataMapper.updateByPrimaryKeySelective(playerData) > 0;
    }

    @Override
    @Transactional(rollbackFor = {Throwable.class})
    public boolean deleteInfo(Integer id) {
        PlayerData playerData = playerDataMapper.selectById(id);
        //获取玩家账号
        Integer playerAccount = playerData.getPlayerAccount();
        //如果redis中已经记录了其权限，那么修改后需要删除树状记录
        String key = "permission";
        String field = "menu:info:" + playerAccount;
        //如果存在，直接删除
        HashOperations hashJedis = redisTemplate.opsForHash();
        hashJedis.delete(key,field);
        playerPositionMapper.deleteByPlayerAccount(playerAccount);
        return playerDataMapper.deleteByPrimaryKey(id) > 0;
    }

    @Override
    public PageInfo<PlayerDataVO> getPlayerInfo(Integer playerAccount, Integer pageNumber, Integer pageSize) {
        PageHelper.startPage(pageNumber,pageSize);
        PlayerDataVO playerDataVO = playerDataMapper.seleteByAccountPlayer(playerAccount);
        //展示前端时权限中文化
        List<PlayerDataVO> playerDataVOList = new ArrayList<>();
        playerDataVO.setPositionId(PositionEnum.getExprByCode(Integer.valueOf(playerDataVO.getPositionId())));
        playerDataVOList.add(playerDataVO);
        PageInfo<PlayerDataVO> page = new PageInfo<>(playerDataVOList);
        return page;
    }

    @Override
    public PlayerData toUpdateByPlayerAccount(Integer playerAccount) {
        PlayerDataVO playerDataVO = playerDataMapper.seleteByAccountPlayer(playerAccount);
        PlayerData playerData = new PlayerData();
        BeanUtils.copyProperties(playerDataVO,playerData);
        return playerData;
    }
}
